
/**
 * Predefined variables
 * Name = baseEventBus
 * DateTime = Fri Feb 11 2022 10:32:43 GMT+0800 (中国标准时间)
 * Author = Shioho
 * FileBasename = baseEventBus.ts
 * FileBasenameNoExtension = baseEventBus
 * URL = db://assets/shioho/scripts/event/baseEventBus.ts
 * ManualUrl = https://docs.cocos.com/creator/3.4/manual/zh/lo
 *
 */

import logHelper from "./logHelper";


export default class baseEventBus<T>{
    private _observersMap: Map<T, Array<Function>> = new Map<T, Array<Function>>();

    public addObserver(eventType: T, func: Function) {
        if (!func) {
            logHelper.error(`事件${eventType}添加失败,不能添加一个空的事件`);
            return;
        }

        let observers = this._observersMap.get(eventType);
        if (!observers) {
            observers = new Array<Function>();
            this._observersMap.set(eventType, observers);
        }

        if (!this.repeatCheck(observers, eventType, func)) {
            observers.push(func);
        }
    }

    public removeObserver(eventType: T, func: Function) {
        if (!func) {
            logHelper.error(`事件(${eventType})移除失败，不能移除一个空的事件`);
            return;
        }

        let observers = this._observersMap.get(eventType);
        if (observers) {
            let idx = observers.indexOf(func);
            if (idx != -1) {
                observers.splice(idx, 1);
                observers.length <= 0 && this._observersMap.delete(eventType);
            }
        }
    }

    public dispatch(eventType: T, ...args) {
        let observers = this._observersMap.get(eventType);
        if (!observers)
            return;

        for (let func of observers) {
            try {
                func && func(args[0]);
            } catch (e) {
                logHelper.error(`EventObserver.Notify Error: \n EventType: ${eventType} \n Message: ${e.stack} `);
            }
        }
    }

    public clear() {
        this._observersMap.clear();
    }

    private repeatCheck(observers: Array<Function>, eventType: T, func: Function): boolean {
        let isRepeat = observers.indexOf(func) != -1;
        if (isRepeat) {
            logHelper.error(`事件${eventType}出现重复订阅`);
        }
        return isRepeat;
    }

}
